package com.oron3.locker;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import com.oron3.lock.R;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Editable;
import android.text.Html;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;

/**
 * Activity which displays a login screen to the user, offering registration as
 * well.
 */
public class LoginActivity extends FragmentActivity {
	/**
	 * The default email to populate the email field with.
	 */
	public static final String EXTRA_UC = "com.oron3.Lock.EXTRA_UC";
	public static final String EXTRA_UC_ENCRYPTED = "com.oron3.Lock.EXTRA_UC_ENCRYPTED";
	public static final String EXTRA_HINT = "com.oron3.Lock.EXTRA_ANSWER_MD5";
	private static final String EXTRA_NUMBER_OF_RETRIES = "com.oron3.Lock.EXTRA_NUMBER_OF_RETRIES";
	private static final String FRAGMENT_IDENTIFIER = "com.oron3.Lock.FRAGMENT_IDENTIFIER";
	// Values for email and password at the time of the login attempt.

	// UI references.

	private View mLoginFormView;
	private View mLoginStatusView;
	private TextView mLoginStatusMessageView;
	private static SharedPreferences dsp;
	private boolean registered = false;

	public static class LoginFragment extends Fragment {
		private String mUC;
		private EditText mUCView;

		@Override
		public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
				final Bundle savedInstanceState) {
			final View inflate = inflater.inflate(R.layout.fragment_login, container,false);
			mUCView = (EditText) inflate.findViewById(R.id.uc);
			final TextView hint = (TextView) inflate.findViewById(R.id.hint);
			final TextView hint_title = (TextView) inflate.findViewById(R.id.hint_title);
			if ( !dsp.contains(EXTRA_HINT) ) {
				hint.setVisibility(View.GONE);
				hint_title.setVisibility(View.GONE);
			} else {
				hint.setText(dsp.getString(EXTRA_HINT, "No hint"));
			}
			final View start = inflate.findViewById(R.id.start);
			start.setOnClickListener(
					new View.OnClickListener() {
						@Override
						public void onClick(final View view) {
							try {
								mUC = mUCView.getText().toString();
								if (TextUtils.isEmpty(mUC)) {
									mUCView.setError(Html.fromHtml("<font color='red'>"+getString(R.string.error_field_required)+"</font>"));
									mUCView.requestFocus();
								} else if (!new AES(mUC).encrypt(LoginActivity.md5(mUC)).equals(dsp.getString(EXTRA_UC, null))) {
									mUCView.setError(Html.fromHtml("<font color='red'>"+getString(R.string.error_incorrect_password)+"</font>"));
									((LoginActivity)getActivity()).wrongPassword();
									mUCView.requestFocus();
								} else {
									((LoginActivity)getActivity()).login(mUC);
								}
							} catch (final Exception e) {
								e.printStackTrace();
							}
						}
					});
			return inflate;
		}
	}
	public static class RegisterFragment extends Fragment {

		private TextView mQuizView;
		private String mQuiz;
		private String mUC;
		private EditText mUCView;
		@Override
		public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
				final Bundle savedInstanceState) {
			final View inflate = inflater.inflate(R.layout.fragment_register, container,false);
			mUCView = (EditText) inflate.findViewById(R.id.uc);
			mQuiz = dsp.getString(EXTRA_HINT, null);
			mQuizView = (EditText) inflate.findViewById(R.id.safety_q);
			mQuizView.setText(mQuiz);
			mQuizView.addTextChangedListener(new TextWatcher() {
				@Override
				public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
					dsp.edit().putString(EXTRA_HINT,mQuizView.getText().toString()).commit();
				}
				@Override
				public void beforeTextChanged(final CharSequence s, final int start, final int count,final int after) {}
				@Override
				public void afterTextChanged(final Editable s) {}
			});

			final View start = inflate.findViewById(R.id.start);
			start.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(final View view) {
					tryLogin();
				}
			});


			return inflate;
		}

		protected void tryLogin() {

			mUC = mUCView.getText().toString();
			try {
				dsp.edit().putString(EXTRA_UC,new AES(mUC).encrypt(LoginActivity.md5(mUC))).commit();

			} catch (final Exception e1) {
				e1.printStackTrace();
			} 
			if (mQuizView==null || mQuizView.length()<=0 ) {
				final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
				builder.setMessage(R.string.not_filled_safty_quiz);
				builder.setTitle(R.string.notice);
				builder.setNegativeButton("No",  new AlertDialog.OnClickListener() {

					@Override
					public void onClick(final DialogInterface dialog, final int which) {

					}

				});
				builder.setPositiveButton("Yes", new AlertDialog.OnClickListener() {

					@Override
					public void onClick(final DialogInterface dialog, final int which) {
						((LoginActivity)getActivity()).login(mUC);
					}

				}); 
				builder.setCancelable(false);
				builder.create().show();
			} else 
				((LoginActivity)getActivity()).login(mUC);

		}
	}
	public static class WaitFragment extends Fragment {

		@Override
		public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
				final Bundle savedInstanceState) {
			return inflater.inflate(R.layout.fragment_wait, container,false);
		}
	}

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);
		if (savedInstanceState!=null) return;
		dsp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		registered=dsp.contains(EXTRA_UC);
		if ( registered ) 
			changeFrgment(new LoginFragment());
		else 
			changeFrgment(new RegisterFragment());
		//		else if (savedInstanceState!=null && savedInstanceState.containsKey(FRAGMENT_IDENTIFIER)) {
		//			savedInstanceState
		//			switch (savedInstanceState.getInt(FRAGMENT_IDENTIFIER)) {
		//			case 
		//			}
		//			fragment = new LoginFragment();
		//		}







	}




	protected void changeFrgment(final Fragment fragment) {
		final FragmentManager fragmentManager = getSupportFragmentManager();
		final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
		fragmentTransaction.replace(R.id.container, fragment);
		fragmentTransaction.commit();
	}




	protected void login(final String mUC) {
		changeFrgment(new WaitFragment());
		final Intent intent = new Intent(this,LockActivity.class);
		intent.putExtra(LockActivity.KEY_INTENT_EXTRA_UC, mUC);
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		startActivity(intent);
		dsp.edit().putInt(EXTRA_NUMBER_OF_RETRIES,0 ).commit();
	}

	public static final String md5(final String s) {
		final String MD5 = "MD5";
		try {
			// Create MD5 Hash
			final MessageDigest digest = java.security.MessageDigest
					.getInstance(MD5);
			digest.update(s.getBytes());
			final byte messageDigest[] = digest.digest();

			// Create Hex String
			final StringBuilder hexString = new StringBuilder();
			for (final byte aMessageDigest : messageDigest) {
				String h = Integer.toHexString(0xFF & aMessageDigest);
				while (h.length() < 2)
					h = "0" + h;
				hexString.append(h);
			}
			return hexString.toString();

		} catch (final NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return "";
	}


	protected void wrongPassword() {
		final int numOfRetries = dsp.getInt(EXTRA_NUMBER_OF_RETRIES, 0)+1;
		dsp.edit().putInt(EXTRA_NUMBER_OF_RETRIES,numOfRetries ).commit();
		if (4==numOfRetries) {
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage(R.string.last_try);
			builder.setTitle(R.string.notice);
			builder.create().show();
		} else if ( 5<=numOfRetries ) {

			deleteDatabase("Lock");
			dsp.edit().clear().commit();
			final AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage(R.string.database_inited);
			builder.setTitle(R.string.notice);
			builder.setNeutralButton(R.string.continue_, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(final DialogInterface dialog, final int which) {
					startActivity(new Intent(LoginActivity.this,LockActivity.class));
					finish();
				}
			});
			builder.create().show();

		}

	}
}